#ifndef __LUOO_MYSQL_CONN_POOL_HPP__
#define __LUOO_MYSQL_CONN_POOL_HPP__

#include <list>

#include <boost/thread.hpp>

#include "luoo_mysql_header.h"

namespace luoo
{
	class mysql_conn_pool
	{
	public:
		typedef MYSQL* mysql_ptr;
	private:
		struct mysql_coon
		{
			mysql_ptr mysql;
			bool idle;
			mysql_coon()
				: mysql(NULL), idle(true)
			{}
			mysql_coon(mysql_ptr ptr)
				: mysql(ptr), idle(true)
			{}
		};
	public:
		mysql_conn_pool()
			: pool_size_(0)
		{}

		void init(std::size_t pool_size)
		{
			pool_size_ = pool_size;
		}

	public:
		bool connect_all(const char *host, unsigned int port, const char *user, const char *passwd, const char* db)
		{
			static bool flag = false;

			for (std::size_t i = 0; i < pool_size_; ++i)
			{
				mysql_ptr mysql = mysql_init(NULL);
				if (NULL == mysql)
					continue;

				bool value = true;
				mysql_options(mysql, MYSQL_OPT_RECONNECT, &value);

				if (NULL == mysql_real_connect(mysql, host, user, passwd, db, port, NULL, CLIENT_MULTI_RESULTS))
					return false;

				mysql_pool_.push_back(mysql_coon(mysql));

				if (!flag)
				{
					std::cout << "mysql client version:"<< mysql_get_client_info() << std::endl;
					std::cout << "mysql server version:"<< mysql_get_server_info(mysql) << std::endl;
					flag = true;
				}
			}

			return true;
		}

		void disconnect_all()
		{
			boost::mutex::scoped_lock lock(mutex_);

			for (coon_pool_type::iterator it = mysql_pool_.begin(); it != mysql_pool_.end(); ++it)
			{
				mysql_close(it->mysql);
			}

			mysql_pool_.clear();
		}

		void ping_all()
		{
			boost::mutex::scoped_lock lock(mutex_);

			if (!mysql_pool_.empty())
			{
				for (coon_pool_type::iterator it = mysql_pool_.begin(); it != mysql_pool_.end(); ++it)
				{
					if (it->idle)
					{
						mysql_ping(it->mysql);
					}
				}
			}
		}

		inline mysql_ptr get_idle()
		{
			boost::mutex::scoped_lock lock(mutex_);

			if (!mysql_pool_.empty())
			{
				for (coon_pool_type::iterator it = mysql_pool_.begin(); it != mysql_pool_.end(); ++it)
				{
					if (it->idle)
					{
						it->idle = false;

						return it->mysql;
					}
				}
			}		
			return NULL;
		}

		void set_idle(mysql_ptr mysql)
		{
			boost::mutex::scoped_lock lock(mutex_);

			if (!mysql_pool_.empty())
			{
				for (coon_pool_type::iterator it = mysql_pool_.begin(); it != mysql_pool_.end(); ++it)
				{
					if (mysql == it->mysql)
					{
						it->idle = true;

						return;
					}
				}
			}		
		}
	private:
		typedef std::list<mysql_coon> coon_pool_type;
	private:
		std::size_t pool_size_;
		boost::mutex mutex_;
		coon_pool_type mysql_pool_;
	};//class mysql_conn_pool
}//namespace luoo

#endif//__LUOO_MYSQL_CONN_POOL_HPP__